package com.bitcola.security.activity.biz;

import cn.hutool.core.util.RandomUtil;
import com.bitcola.security.activity.constant.PrizeConstant;
import com.bitcola.entity.RedPacketHelp;
import com.bitcola.entity.RedPacketHelpLog;
import com.bitcola.security.activity.feign.IDataServiceFeign;
import com.bitcola.security.activity.feign.IMeFeign;
import com.bitcola.security.activity.mapper.BalanceChangeLogMapper;
import com.bitcola.security.activity.mapper.ColaUserBalanceMapper;
import com.bitcola.security.activity.mapper.RedPacketHelpLogMapper;
import com.bitcola.security.activity.mapper.RedPacketHelpMapper;
import com.bitcola.security.auth.common.util.EncoderUtil;
import com.bitcola.security.common.biz.BaseBiz;
import com.bitcola.security.common.constant.BalanceTypeConstants;
import com.bitcola.security.common.constant.FinancialConstant;
import com.bitcola.security.common.exception.RepeatException;
import com.bitcola.security.common.util.Snowflake;
import com.bitcola.entity.BalanceChange;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author wx
 * @create 2018-11-29 21:00
 **/
@Service
@Log4j2
public class RedPacketBiz   extends BaseBiz<RedPacketHelpMapper, RedPacketHelp> {

    @Autowired
    RedPacketHelpMapper redPacketHelpMapper;

    @Autowired
    RedPacketHelpLogMapper redPacketHelpLogMapper;
    @Resource
    IDataServiceFeign dataServiceFeign;

    @Autowired
    BalanceChangeLogMapper balanceChangeLogMapper;
    @Autowired
    ColaUserBalanceMapper colaUserBalanceMapper;

    @Autowired
            BalanceChangeBiz balanceChangeBiz;

    @Resource
    IMeFeign meFeign;


    Snowflake snowflake=new Snowflake(4,11);
    @Transactional
    public RedPacketHelp apply(String userId) {

        Date now = new Date();
        String coinCode = dataServiceFeign.getConfig("red_packet_coin");
        BigDecimal initAmount = new BigDecimal(dataServiceFeign.getConfig("red_packet_init_amount"));
        BigDecimal finishAmount = new BigDecimal(dataServiceFeign.getConfig("red_packet_finish_amount"));
        initAmount=initAmount.subtract(BigDecimal.valueOf(RandomUtil.randomDouble(0.06d,0.15d))).setScale(3,RoundingMode.DOWN);
        long expireTime = ((now.getTime() + Long.parseLong(dataServiceFeign.getConfig("red_packet_expire"))) / 10000) * 10000;

        Example example = new Example(RedPacketHelp.class);
        example.createCriteria().andEqualTo("userId", userId).andGreaterThan("expireTime", now).andNotEqualTo("status","WITHDRAWED");

        var count = redPacketHelpMapper.selectCountByExample(example);
        if (count> 0) {
            throw new RepeatException("input repeat");
        }
        RedPacketHelp redPacketHelp = new RedPacketHelp();
        redPacketHelp.setFactor(BigDecimal.ZERO);
        redPacketHelp.setId(UUID.randomUUID().toString());
        redPacketHelp.setCreateTime(now);
        redPacketHelp.setCoinCode(coinCode);
        redPacketHelp.setExpireTime(new Date(expireTime));
        redPacketHelp.setUserId(userId);
        redPacketHelp.setCurrentAmount(initAmount);

        redPacketHelp.setStatus("UNSHARE");
        redPacketHelp.setIntiAmount(initAmount);
        redPacketHelp.setFinishAmount(finishAmount);
        redPacketHelpMapper.insert(redPacketHelp);
        return redPacketHelp;

    }

    @Transactional
    public RedPacketHelpLog share(String redHelpId, String userId,String ip) {
        return         help(redHelpId,userId,"share",ip);


    }

    public int getNumer(String ip,String shareId,String type){
        int typeFactor=1;
        if(type.equals("helpNew")||type.equals("help")){
            var number=statisticsNumber(shareId,type);
            if(number>150){
                typeFactor=number-150;
            }

        }
        int ipNum=meFeign.getIpSum(ip);
        int num=3;
        if(ipNum<num) return typeFactor;
        log.info("ip{}获取参数变成:{}",ip,ipNum-14);
        return  (ipNum-(num-1))*typeFactor;

    }

    @Transactional
    public RedPacketHelpLog help(String redHelpId,String userId,String type ,String ip){
//        String coinCode = dataServiceFeign.getConfig("red_packet_coin");
        RedPacketHelp redPacketHelp = redPacketHelpMapper.selectByPrimaryKey(redHelpId);
        if(redPacketHelp.getExpireTime().getTime()<System.currentTimeMillis())
        if(!type.equals("share")){
            if(redPacketHelp.getUserId().equals(userId))throw new RepeatException("不能自己给自己助力");
        }
        int index=0;
        switch (type){
            case "share":{
                index = redPacketHelpMapper.updateStatus("SHARED", "UNSHARE", redHelpId);
                redPacketHelp.setStatus("SHARED");
                break;
            }
            case "help":
            case "helpNew":
            case "kyc": {
                index = redPacketHelpMapper.updateStatus("SHARED", "SHARED", redHelpId);
                redPacketHelp.setStatus("SHARED");

                break;
            }
        }


        if (index == 0) throw new RepeatException("input repeat");

        BigDecimal originAmount = redPacketHelp.getCurrentAmount();
        BigDecimal newFoctor = caculateFactor(type, redPacketHelp.getFactor(),getNumer(ip,redHelpId,type));
        BigDecimal currentAmount = new BigDecimal(sigMoid(newFoctor.doubleValue())).setScale(4, RoundingMode.DOWN);
        currentAmount=currentAmount.add(redPacketHelp.getIntiAmount());
        BigDecimal change = currentAmount.subtract(originAmount);
        redPacketHelp.setFactor(newFoctor);
        redPacketHelp.setCurrentAmount(currentAmount);
        RedPacketHelpLog redPacketHelpLog = new RedPacketHelpLog();
        redPacketHelpLog.setId(UUID.randomUUID().toString());
        redPacketHelpLog.setAmount(change);
        redPacketHelpLog.setCreateTime(new Date());
        redPacketHelpLog.setRedPacketHelpId(redHelpId);
        redPacketHelpLog.setUserId(userId);
        redPacketHelpLog.setInitiatorId(redPacketHelp.getUserId());
        redPacketHelpLog.setType(type);
        try {
            redPacketHelpLogMapper.insert(redPacketHelpLog);
        }catch (Exception e){
            throw new RepeatException("input repeat");
        }
        if (currentAmount.compareTo(redPacketHelp.getFinishAmount()) >= 0) {
            currentAmount = redPacketHelp.getFinishAmount();
            redPacketHelp.setCurrentAmount(currentAmount);
            redPacketHelp.setStatus("FINISHED");

        }
        redPacketHelpMapper.updateByPrimaryKey(redPacketHelp);


        return redPacketHelpLog;
}

@Transactional
    public BalanceChange withdraw(String shareId){
     int  index = redPacketHelpMapper.updateStatus("WITHDRAWED", "FINISHED", shareId);
     if(index==0)             throw new RepeatException("input repeat");
    RedPacketHelp redPacketHelp = redPacketHelpMapper.selectByPrimaryKey(shareId);
     var log= balanceChangeBiz.createChange(redPacketHelp.getUserId(),BalanceTypeConstants.BALANCE,PrizeConstant.RED_PACK,redPacketHelp.getFinishAmount(),FinancialConstant.ACTIVITY_REWARD,redPacketHelp.getCoinCode());
    colaUserBalanceMapper.changeUserBanlance(redPacketHelp.getUserId(),redPacketHelp.getCoinCode(),redPacketHelp.getFinishAmount(),BigDecimal.ZERO,BigDecimal.ZERO,BigDecimal.ZERO,BigDecimal.ZERO, BigDecimal.ZERO,EncoderUtil.BALANCE_KEY);

    return log;


}


    public boolean isHelped(String redHelpId,String userId){
        Example example = new Example(RedPacketHelpLog.class);
        example.createCriteria().andEqualTo("userId", userId).andEqualTo("redPacketHelpId", redHelpId);
        var list = redPacketHelpLogMapper.selectByExample(example);
        return list.size()>0;

    }


    public List<RedPacketHelpLog>search(String userId)
    {
        Example example = new Example(RedPacketHelpLog.class);
        example.createCriteria().andEqualTo("initiatorId", userId);

        example.orderBy("createTime").desc();
        var list = redPacketHelpLogMapper.selectByExample(example);
        return  list;


    }

    public static BigDecimal caculateFactor(String type, BigDecimal factor,int number) {


        factor = factor.add((getFactor(type)).divide(BigDecimal.valueOf(number),5,RoundingMode.DOWN));


        return factor;
    }

    public static BigDecimal getFactor(String type) {
        switch (type) {
            case "share": {
                return BigDecimal.valueOf(0.4);

            }
            case "help":{
                return BigDecimal.valueOf(0.0016);
            }
            case "kyc":{

                return BigDecimal.valueOf(0.057);
            }case "helpNew":{
                return BigDecimal.valueOf(0.016);

            }

        }
        return BigDecimal.ZERO;
    }

    public boolean juedgeRepeat(String userId,String shareId){
        Example example = new Example(RedPacketHelpLog.class);
        example.createCriteria().andEqualTo("userId", userId).andEqualTo("redPacketHelpId",shareId);
        return redPacketHelpLogMapper.selectCountByExample(example)>0;

    }

    public static double sigMoid(double value) {
        value=value;
        double ey = Math.pow(Math.E, -value);
        double result = 1 / (1 + ey);
        result=result-0.5;
        return result*12.2;
    }


    public int statisticsNumber(String shareId,String type)
    {
        Example example = new Example(RedPacketHelpLog.class);
        example.createCriteria().andEqualTo("redPacketHelpId", shareId).andEqualTo("type",type);
        return redPacketHelpLogMapper.selectCountByExample(example);
    }
    public static void main(String []s){
        String []types={"help","helpNew","kyc"};
        BigDecimal factor=BigDecimal.ZERO;
        BigDecimal init=BigDecimal.valueOf(23.89);
        BigDecimal current=BigDecimal.valueOf(23.89);
        BigDecimal finals=BigDecimal.valueOf(30);

        BigDecimal temp;

        int i=1;
        while(current.compareTo(finals)<0){
            String type=types[1];
            temp=current;
            factor=  factor.add(getFactor(types[1]));

            current= BigDecimal.valueOf(sigMoid(factor.doubleValue())).add(init);
            System.out.println("第"+(++i)+"论");
            System.out.println(type+"助力 获得"+(current.subtract(temp)));

        }
        System.out.println(factor);






    }


}
